﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;

namespace Smart.Web.Mobile
{
    /// <summary>
    /// 
    /// </summary>
    public class CarrierSettings
    {
        private readonly Carrier carrier;

        private readonly List<Pictgram> pictgrams = new List<Pictgram>();

        private readonly Dictionary<int, Pictgram> noToPictgram = new Dictionary<int, Pictgram>();
        private readonly Dictionary<char, Pictgram> pictgramByUnicode = new Dictionary<char, Pictgram>();
        private readonly Dictionary<char, char[]> pictgramConvert = new Dictionary<char,char[]>();

        private readonly Dictionary<char, byte[]> unicodeToSjis = new Dictionary<char, byte[]>();
        private readonly Dictionary<int, char> sjisToUnicode = new Dictionary<int, char>();

        /// <summary>
        /// 
        /// </summary>
        public List<Pictgram> Pictgrams
        {
            get { return this.pictgrams; }
        }

        /// <summary>
        /// 
        /// </summary>
        public Carrier Carrier
        {
            get { return this.carrier; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="carrier"></param>
        public CarrierSettings(Carrier carrier)
        {
            this.carrier = carrier;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pictgram"></param>
        public void AddPictgram(Pictgram pictgram)
        {
            this.pictgrams.Add( pictgram );
            this.noToPictgram[ pictgram.No ] = pictgram;
            this.pictgramByUnicode[ pictgram.Unicode ] = pictgram;

            this.unicodeToSjis[ pictgram.Unicode ] = pictgram.Sjis;
            if( pictgram.Sjis != null )
            {
                this.sjisToUnicode[ ( pictgram.Sjis[ 0 ] << 8 ) + pictgram.Sjis[ 1 ] ] = pictgram.Unicode;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        public void AddConvert(char src, char[] dst)
        {
            this.pictgramConvert[ src ] = dst;
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dump()
        {
            // Pictgrams
            Debug.WriteLine( "*** Pictgrams ***" );

            Debug.WriteLine( String.Format( "Count={0}", this.pictgrams.Count) );

            foreach( Pictgram pictgram in this.pictgrams )
            {
                Debug.WriteLine( String.Format( "No=[{0,4}], Sjis=[{1}], Unicode=[{2}], Name=[{3}]",
                                                pictgram.No, MobileUtil.SjisToHex( pictgram.Sjis ),
                                                MobileUtil.UnicodeToHex( pictgram.Unicode ), pictgram.Name ) );
            }

            // Encoding
            Debug.WriteLine( "*** Encoding ***" );

            foreach( char src in this.unicodeToSjis.Keys.OrderBy( c => c ) )
            {
                if( this.unicodeToSjis[ src ] != null )
                {
                    int sjis = ( this.unicodeToSjis[ src ][ 0 ] << 8 ) + this.unicodeToSjis[ src ][ 1 ];
                    char unicode = this.sjisToUnicode[ sjis ];

                    Debug.WriteLine( String.Format( "Sjis=[{0}], Unicode=[{1}], Match=[{2}]",
                                                    MobileUtil.SjisToHex( this.unicodeToSjis[ src ] ),
                                                    MobileUtil.UnicodeToHex( unicode ),
                                                    src == unicode ) );
                }
            }

            Debug.WriteLine( String.Format( "Count={0}", this.unicodeToSjis.Count ) );

            // Convert
            Debug.WriteLine( "*** Convert ***" );

            foreach( char src in this.pictgramConvert.Keys.OrderBy( c => c ) )
            {
                Debug.WriteLine( String.Format( "Unicode=[{0}], Convert=[{1}]",
                                                MobileUtil.UnicodeToHex( src ),
                                                MobileUtil.UnicodeToHex( this.pictgramConvert[ src ] ) ) );
            }

            Debug.WriteLine( String.Format( "Count={0}", this.pictgramConvert.Count ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pictgramTreat"></param>
        /// <returns></returns>
        public MobileEncoding GetMobileEncoding(string name, PictgramTreat pictgramTreat)
        {
            if( name.Equals( "Shift_JIS", StringComparison.OrdinalIgnoreCase ) )
            {
                return new MobileSJISEncoding( pictgramTreat, this.unicodeToSjis, this.sjisToUnicode );
            }

            if( name.Equals( "UTF-8", StringComparison.OrdinalIgnoreCase ) )
            {
                return new MobileUTF8Encoding( pictgramTreat );
            }

            throw new ArgumentNullException( "name" );
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="no"></param>
        /// <returns></returns>
        public Pictgram GetPictgramByNo(int no)
        {
            Pictgram pictgram;
            this.noToPictgram.TryGetValue( no, out pictgram );
            return pictgram;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public Pictgram GetPictgramByUnicode(char c)
        {
            Pictgram pictgram;
            this.pictgramByUnicode.TryGetValue( c, out pictgram );
            return pictgram;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public char[] Convert(char src)
        {
            char[] dst;
            this.pictgramConvert.TryGetValue( src, out dst );
            return dst;
        }
    }
}
